﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using l1cs.server.model.Instance;
using l1cs.server.templates;
using l1cs.server.serverpackets;
using l1cs.server.model.skill;
using l1cs.server.datatables;
using l1cs.server.clientpackets;

namespace l1cs.server.model
{
    public class L1EquipmentSlot
    {
        private static Logger _log = Logger.getLogger( typeof( L1EquipmentSlot ).FullName );

        private L1PcInstance _owner;

        /// <summary>効果中のセットアイテム</summary>
        private List<L1ArmorSet> _currentArmorSet;

        private L1ItemInstance _weapon;

        private List<L1ItemInstance> _armors;

        public L1EquipmentSlot( L1PcInstance owner )
        {
            _owner = owner;

            _armors = new List<L1ItemInstance>();
            _currentArmorSet = new List<L1ArmorSet>();
        }

        private void setWeapon( L1ItemInstance weapon )
        {
            _owner.setWeapon( weapon );
            _owner.setCurrentWeapon( weapon.getItem().getType1() );
            weapon.startEquipmentTimer( _owner );
            _weapon = weapon;
        }

        public L1ItemInstance getWeapon()
        {
            return _weapon;
        }

        private void setArmor( L1ItemInstance armor )
        {
            L1Item item = armor.getItem();
            int itemId = armor.getItem().getItemId();

            _owner.addAc( item.get_ac() - armor.getEnchantLevel() - armor.getAcByMagic() );
            _owner.addDamageReductionByArmor( item.getDamageReduction() );
            _owner.addWeightReduction( item.getWeightReduction() );
            _owner.addHitModifierByArmor( item.getHitModifierByArmor() );
            _owner.addDmgModifierByArmor( item.getDmgModifierByArmor() );
            _owner.addBowHitModifierByArmor( item.getBowHitModifierByArmor() );
            _owner.addBowDmgModifierByArmor( item.getBowDmgModifierByArmor() );
            _owner.addEarth( item.get_defense_earth() );
            _owner.addWind( item.get_defense_wind() );
            _owner.addWater( item.get_defense_water() );
            _owner.addFire( item.get_defense_fire() );
            _owner.addRegistStun( item.get_regist_stun() );
            _owner.addRegistStone( item.get_regist_stone() );
            _owner.addRegistSleep( item.get_regist_sleep() );
            _owner.add_regist_freeze( item.get_regist_freeze() );
            _owner.addRegistSustain( item.get_regist_sustain() );
            _owner.addRegistBlind( item.get_regist_blind() );

            _armors.Add( armor );

            foreach ( L1ArmorSet armorSet in L1ArmorSet.getAllSet() )
            {
                if ( armorSet.isPartOfSet( itemId ) && armorSet.isValid( _owner ) )
                {
                    if ( armor.getItem().getType2() == 2 && armor.getItem().getType() == 9 )
                    {
                        // ring
                        if ( !armorSet.isEquippedRingOfArmorSet( _owner ) )
                        {
                            armorSet.giveEffect( _owner );
                            _currentArmorSet.Add( armorSet );
                        }
                    }
                    else
                    {
                        armorSet.giveEffect( _owner );
                        _currentArmorSet.Add( armorSet );
                    }
                }
            }

            if ( itemId == 20077 || itemId == 20062 || itemId == 120077 )
            {
                if ( !_owner.hasSkillEffect( L1SkillId.INVISIBILITY ) )
                {
                    _owner.killSkillEffectTimer( L1SkillId.BLIND_HIDING );
                    _owner.setSkillEffect( L1SkillId.INVISIBILITY, 0 );
                    _owner.sendPackets( new S_Invis( _owner.getId(), 1 ) );
                    _owner.broadcastPacketForFindInvis( new S_RemoveObject( _owner ), false );
                    // _owner.broadcastPacket(new S_RemoveObject(_owner));
                }
            }
            if ( itemId == 20288 )
            {
                // ROTC
                _owner.sendPackets( new S_Ability( 1, true ) );
            }
            if ( itemId == 20383 )
            {
                // 騎馬用ヘルム
                if ( armor.getChargeCount() != 0 )
                {
                    armor.setChargeCount( armor.getChargeCount() - 1 );
                    _owner.getInventory().updateItem( armor, L1PcInventory.COL_CHARGE_COUNT );
                }
            }
            armor.startEquipmentTimer( _owner );
        }

        public List<L1ItemInstance> getArmors()
        {
            return _armors;
        }

        private void removeWeapon( L1ItemInstance weapon )
        {
            int itemId = weapon.getItem().getItemId();
            _owner.setWeapon( null );
            _owner.setCurrentWeapon( 0 );
            weapon.stopEquipmentTimer( _owner );
            _weapon = null;
            if ( _owner.hasSkillEffect( L1SkillId.COUNTER_BARRIER ) )
            {
                _owner.removeSkillEffect( L1SkillId.COUNTER_BARRIER );
            }
        }

        private void removeArmor( L1ItemInstance armor )
        {
            L1Item item = armor.getItem();
            int itemId = armor.getItem().getItemId();

            _owner.addAc( -( item.get_ac() - armor.getEnchantLevel() - armor.getAcByMagic() ) );
            _owner.addDamageReductionByArmor( -item.getDamageReduction() );
            _owner.addWeightReduction( -item.getWeightReduction() );
            _owner.addHitModifierByArmor( -item.getHitModifierByArmor() );
            _owner.addDmgModifierByArmor( -item.getDmgModifierByArmor() );
            _owner.addBowHitModifierByArmor( -item.getBowHitModifierByArmor() );
            _owner.addBowDmgModifierByArmor( -item.getBowDmgModifierByArmor() );
            _owner.addEarth( -item.get_defense_earth() );
            _owner.addWind( -item.get_defense_wind() );
            _owner.addWater( -item.get_defense_water() );
            _owner.addFire( -item.get_defense_fire() );
            _owner.addRegistStun( -item.get_regist_stun() );
            _owner.addRegistStone( -item.get_regist_stone() );
            _owner.addRegistSleep( -item.get_regist_sleep() );
            _owner.add_regist_freeze( -item.get_regist_freeze() );
            _owner.addRegistSustain( -item.get_regist_sustain() );
            _owner.addRegistBlind( -item.get_regist_blind() );

            foreach ( L1ArmorSet armorSet in L1ArmorSet.getAllSet() )
            {
                if ( armorSet.isPartOfSet( itemId )
                 && _currentArmorSet.Contains( armorSet )
                 && !armorSet.isValid( _owner ) )
                {
                    armorSet.cancelEffect( _owner );
                    _currentArmorSet.Remove( armorSet );
                }
            }

            if ( itemId == 20077 || itemId == 20062 || itemId == 120077 )
            {
                _owner.delInvis(); // インビジビリティ状態解除
            }
            if ( itemId == 20288 )
            {
                // ROTC
                _owner.sendPackets( new S_Ability( 1, false ) );
            }
            armor.stopEquipmentTimer( _owner );

            _armors.Remove( armor );
        }

        public void set( L1ItemInstance equipment )
        {
            L1Item item = equipment.getItem();
            if ( item.getType2() == 0 )
            {
                return;
            }

            if ( item.get_addhp() != 0 )
            {
                _owner.addMaxHp( item.get_addhp() );
            }
            if ( item.get_addmp() != 0 )
            {
                _owner.addMaxMp( item.get_addmp() );
            }
            _owner.addStr( item.get_addstr() );
            _owner.addCon( item.get_addcon() );
            _owner.addDex( item.get_adddex() );
            _owner.addInt( item.get_addint() );
            _owner.addWis( item.get_addwis() );
            if ( item.get_addwis() != 0 )
            {
                _owner.resetBaseMr();
            }
            _owner.addCha( item.get_addcha() );

            int addMr = 0;
            addMr += equipment.getMr();
            if ( item.getItemId() == 20236 && _owner.isElf() )
            {
                addMr += 5;
            }
            if ( addMr != 0 )
            {
                _owner.addMr( addMr );
                _owner.sendPackets( new S_SPMR( _owner ) );
            }
            if ( item.get_addsp() != 0 )
            {
                _owner.addSp( item.get_addsp() );
                _owner.sendPackets( new S_SPMR( _owner ) );
            }
            if ( item.isHasteItem() )
            {
                _owner.addHasteItemEquipped( 1 );
                _owner.removeHasteSkillEffect();
                if ( _owner.getMoveSpeed() != 1 )
                {
                    _owner.setMoveSpeed( 1 );
                    _owner.sendPackets( new S_SkillHaste( _owner.getId(), 1, -1 ) );
                    _owner.broadcastPacket( new S_SkillHaste( _owner.getId(), 1, 0 ) );
                }
            }
            if ( item.getItemId() == 20383 )
            {
                // 騎馬用ヘルム
                if ( _owner.hasSkillEffect( L1SkillId.STATUS_BRAVE ) )
                {
                    _owner.killSkillEffectTimer( L1SkillId.STATUS_BRAVE );
                    _owner.sendPackets( new S_SkillBrave( _owner.getId(), 0, 0 ) );
                    _owner.broadcastPacket( new S_SkillBrave( _owner.getId(), 0, 0 ) );
                    _owner.setBraveSpeed( 0 );
                }
            }
            _owner.getEquipSlot().setMagicHelm( equipment );

            if ( item.getType2() == 1 )
            {
                setWeapon( equipment );
            }
            else if ( item.getType2() == 2 )
            {
                setArmor( equipment );
                _owner.sendPackets( new S_SPMR( _owner ) );
            }
        }

        public void remove( L1ItemInstance equipment )
        {
            L1Item item = equipment.getItem();
            if ( item.getType2() == 0 )
            {
                return;
            }

            if ( item.get_addhp() != 0 )
            {
                _owner.addMaxHp( -item.get_addhp() );
            }
            if ( item.get_addmp() != 0 )
            {
                _owner.addMaxMp( -item.get_addmp() );
            }
            _owner.addStr( (byte)-item.get_addstr() );
            _owner.addCon( (byte)-item.get_addcon() );
            _owner.addDex( (byte)-item.get_adddex() );
            _owner.addInt( (byte)-item.get_addint() );
            _owner.addWis( (byte)-item.get_addwis() );
            if ( item.get_addwis() != 0 )
            {
                _owner.resetBaseMr();
            }
            _owner.addCha( (byte)-item.get_addcha() );

            int addMr = 0;
            addMr -= equipment.getMr();
            if ( item.getItemId() == 20236 && _owner.isElf() )
            {
                addMr -= 5;
            }
            if ( addMr != 0 )
            {
                _owner.addMr( addMr );
                _owner.sendPackets( new S_SPMR( _owner ) );
            }
            if ( item.get_addsp() != 0 )
            {
                _owner.addSp( -item.get_addsp() );
                _owner.sendPackets( new S_SPMR( _owner ) );
            }
            if ( item.isHasteItem() )
            {
                _owner.addHasteItemEquipped( -1 );
                if ( _owner.getHasteItemEquipped() == 0 )
                {
                    _owner.setMoveSpeed( 0 );
                    _owner.sendPackets( new S_SkillHaste( _owner.getId(), 0, 0 ) );
                    _owner.broadcastPacket( new S_SkillHaste( _owner.getId(), 0, 0 ) );
                }
            }
            _owner.getEquipSlot().removeMagicHelm( _owner.getId(), equipment );

            if ( item.getType2() == 1 )
            {
                removeWeapon( equipment );
            }
            else if ( item.getType2() == 2 )
            {
                removeArmor( equipment );
            }
        }

        public void setMagicHelm( L1ItemInstance item )
        {
            switch ( item.getItemId() )
            {
                case 20013:
                    _owner.setSkillMastery( L1SkillId.PHYSICAL_ENCHANT_DEX );
                    _owner.setSkillMastery( L1SkillId.HASTE );
                    _owner.sendPackets( new S_AddSkill( 0, 0, 0, 2, 0, 4, 0, 0, 0, 0, 0,
                            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ) );
                    break;
                case 20014:
                    _owner.setSkillMastery( L1SkillId.HEAL );
                    _owner.setSkillMastery( L1SkillId.EXTRA_HEAL );
                    _owner.sendPackets( new S_AddSkill( 1, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0,
                            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ) );
                    break;
                case 20015:
                    _owner.setSkillMastery( L1SkillId.ENCHANT_WEAPON );
                    _owner.setSkillMastery( L1SkillId.DETECTION );
                    _owner.setSkillMastery( L1SkillId.PHYSICAL_ENCHANT_STR );
                    _owner.sendPackets( new S_AddSkill( 0, 24, 0, 0, 0, 2, 0, 0, 0, 0, 0,
                            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ) );
                    break;
                case 20008:
                    _owner.setSkillMastery( L1SkillId.HASTE );
                    _owner.sendPackets( new S_AddSkill( 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0,
                            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ) );
                    break;
                case 20023:
                    _owner.setSkillMastery( L1SkillId.GREATER_HASTE );
                    _owner.sendPackets( new S_AddSkill( 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0,
                            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ) );
                    break;
            }
        }

        public void removeMagicHelm( int objectId, L1ItemInstance item )
        {
            switch ( item.getItemId() )
            {
                case 20013: // 魔法のヘルム：迅速
                    if ( !SkillsTable.getInstance().spellCheck( objectId, L1SkillId.PHYSICAL_ENCHANT_DEX ) )
                    {
                        _owner.removeSkillMastery( L1SkillId.PHYSICAL_ENCHANT_DEX );
                        _owner.sendPackets( new S_DelSkill( 0, 0, 0, 2, 0, 0, 0, 0, 0, 0,
                                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ) );
                    }
                    if ( !SkillsTable.getInstance().spellCheck( objectId, L1SkillId.HASTE ) )
                    {
                        _owner.removeSkillMastery( L1SkillId.HASTE );
                        _owner.sendPackets( new S_DelSkill( 0, 0, 0, 0, 0, 4, 0, 0, 0, 0,
                                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ) );
                    }
                    break;
                case 20014: // 魔法のヘルム：治癒
                    if ( !SkillsTable.getInstance().spellCheck( objectId, L1SkillId.HEAL ) )
                    {
                        _owner.removeSkillMastery( L1SkillId.HEAL );
                        _owner.sendPackets( new S_DelSkill( 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ) );
                    }
                    if ( !SkillsTable.getInstance().spellCheck( objectId, L1SkillId.EXTRA_HEAL ) )
                    {
                        _owner.removeSkillMastery( L1SkillId.EXTRA_HEAL );
                        _owner.sendPackets( new S_DelSkill( 0, 0, 4, 0, 0, 0, 0, 0, 0, 0,
                                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ) );
                    }
                    break;
                case 20015: // 魔法のヘルム：力
                    if ( !SkillsTable.getInstance().spellCheck( objectId, L1SkillId.ENCHANT_WEAPON ) )
                    {
                        _owner.removeSkillMastery( L1SkillId.ENCHANT_WEAPON );
                        _owner.sendPackets( new S_DelSkill( 0, 8, 0, 0, 0, 0, 0, 0, 0, 0,
                                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ) );
                    }
                    if ( !SkillsTable.getInstance().spellCheck( objectId, L1SkillId.DETECTION ) )
                    {
                        _owner.removeSkillMastery( L1SkillId.DETECTION );
                        _owner.sendPackets( new S_DelSkill( 0, 16, 0, 0, 0, 0, 0, 0, 0,
                                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ) );
                    }
                    if ( !SkillsTable.getInstance().spellCheck( objectId, L1SkillId.PHYSICAL_ENCHANT_STR ) )
                    {
                        _owner.removeSkillMastery( L1SkillId.PHYSICAL_ENCHANT_STR );
                        _owner.sendPackets( new S_DelSkill( 0, 0, 0, 0, 0, 2, 0, 0, 0, 0,
                                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ) );
                    }
                    break;
                case 20008: // マイナーウィンドヘルム
                    if ( !SkillsTable.getInstance().spellCheck( objectId, L1SkillId.HASTE ) )
                    {
                        _owner.removeSkillMastery( L1SkillId.HASTE );
                        _owner.sendPackets( new S_DelSkill( 0, 0, 0, 0, 0, 4, 0, 0, 0, 0,
                                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ) );
                    }
                    break;
                case 20023: // ウィンドヘルム
                    if ( !SkillsTable.getInstance().spellCheck( objectId, L1SkillId.GREATER_HASTE ) )
                    {
                        _owner.removeSkillMastery( L1SkillId.GREATER_HASTE );
                        _owner.sendPackets( new S_DelSkill( 0, 0, 0, 0, 0, 0, 32, 0, 0,
                                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ) );
                    }
                    break;
            }
        }
    }
}
